package com.dd.framework.advice;

import com.dd.common.entity.CommonResult;
import com.dd.common.entity.ResultCode;
import com.dd.common.exception.RequestParamException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.dd.common.exception.BussinessException;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 拦截业务异常
     * @param response
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(BussinessException.class)
    public CommonResult globalBusException(HttpServletResponse response, BussinessException ex){
        log.error("业务错误：" ,ex );
        CommonResult result = new CommonResult(ex.getErrorCode(),ex.getErrorMsg());
        return result;
    }


    /**
     * 拦截入参验证异常
     * @param response
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(ConstraintViolationException.class)
    public CommonResult globalViolationException(HttpServletResponse response, ConstraintViolationException ex){
        log.error("入参验证：" ,ex );
        String collect = ex.getConstraintViolations().stream().filter(Objects::nonNull)
                .map(cv -> cv == null ? "null" : cv.getPropertyPath() + ": " + cv.getMessage())
                .collect(Collectors.joining(", "));
        log.error("请求参数异常",collect);
        CommonResult result = new CommonResult(ResultCode.VALIDATE_FAILED.getCode(),ex.getMessage());
        return result;
    }

    /**
     * 拦截运行中请求参数入参验证异常
     * @param response
     * @param ex
     * @return 返回错误编码，以及发生错误的字段名称
     */
    @ResponseBody
    @ExceptionHandler(RequestParamException.class)
    public CommonResult globalRequestParamException(HttpServletResponse response, RequestParamException ex){
        log.error(String.format("请求参数中{}字段错误，错误原因{}",ex.getField(),ex.getResultCode().getMessage()),ex);
        CommonResult result = new CommonResult(ex.getResultCode().getCode(),ex.getField());
        return result;
    }

    /**
     * 拦截未知的运行时异常
     * @param response
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(RuntimeException.class)
    public CommonResult globalRuntimeException(HttpServletResponse response, RuntimeException ex){
        log.error("业务错误：" ,ex );
        CommonResult result = new CommonResult(ResultCode.SYSTEM_EXCEPTION.getCode(),ResultCode.SYSTEM_EXCEPTION.getMessage());
        return result;
    }
}
